Small Website to play Web-based games.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 

111 рядки
2.6 KiB

  1. import {GetServerSideProps, NextPage} from 'next';
  2. import Head from 'next/head';
  3. import {useRouter} from 'next/router';
  4. import {useEffect, useMemo, useRef, useState} from 'react';
  5. import {Game} from '../../../utils/games';
  6. type GamePageProps = {
  7. game: Game,
  8. }
  9. const GamePlayPage: NextPage<GamePageProps> = ({
  10. game,
  11. }) => {
  12. const router = useRouter();
  13. const [wrapperWidth, setWrapperWidth] = useState<number>();
  14. const { id } = router.query;
  15. const timeoutRef = useRef(null as NodeJS.Timeout | null);
  16. const aspectRatio = useMemo(() => game.data.aspectRatio, [game]);
  17. useEffect(() => {
  18. const handleResize = () => {
  19. const currentAspectRatio = window.innerWidth / window.innerHeight;
  20. if (currentAspectRatio > aspectRatio) {
  21. if (timeoutRef.current) {
  22. window.clearTimeout(timeoutRef.current);
  23. }
  24. timeoutRef.current = setTimeout(() => {
  25. setWrapperWidth(window.innerHeight * aspectRatio);
  26. }, 50);
  27. } else {
  28. setWrapperWidth(undefined);
  29. }
  30. }
  31. window.addEventListener('resize', handleResize);
  32. handleResize();
  33. return () => {
  34. window.removeEventListener('resize', handleResize);
  35. }
  36. }, [aspectRatio]);
  37. if (id) {
  38. return (
  39. <>
  40. <Head>
  41. <title>{game.name}</title>
  42. </Head>
  43. <div
  44. style={{
  45. width: '100%',
  46. height: '100%',
  47. display: 'flex',
  48. justifyContent: 'center',
  49. alignItems: 'center',
  50. position: 'fixed',
  51. top: 0,
  52. left: 0,
  53. backgroundColor: 'black',
  54. }}
  55. >
  56. <div
  57. style={{
  58. width: wrapperWidth ?? '100%',
  59. paddingBottom: `${100 / aspectRatio}%`,
  60. position: 'relative',
  61. }}
  62. >
  63. <object
  64. style={{
  65. width: '100%',
  66. height: '100%',
  67. position: 'absolute',
  68. top: 0,
  69. left: 0,
  70. objectPosition: 'center',
  71. }}
  72. >
  73. <embed
  74. src={`/games/${id}/${game.main}`}
  75. width="100%"
  76. height="100%"
  77. />
  78. </object>
  79. </div>
  80. </div>
  81. </>
  82. );
  83. }
  84. return null;
  85. }
  86. export const getServerSideProps: GetServerSideProps = async (ctx) => {
  87. const response = await fetch(`http://localhost:3000/api/games/${ctx.query.id}`);
  88. if (response.status !== 200) {
  89. return {
  90. notFound: true,
  91. }
  92. }
  93. const game = await response.json();
  94. return {
  95. props: {
  96. game,
  97. }
  98. }
  99. }
  100. export default GamePlayPage;